package chapter.fourth.item22;

import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

final class MySet<E> extends AbstractSet<E> {

	private static final Object persent = new Object();
	private final HashMap<E,Object> map;
	
	public MySet() {
		super();
		map = new HashMap<E,Object>();
	}
	
	public MySet(Collection<? extends E> c){
		map = new HashMap<E,Object>(Math.max((int) (c.size()/.75f) + 1, 16));
		addAll(c);
	}
		
	@Override
	public Iterator<E> iterator() {
		return new MyIterator();
	}

	@Override
	public int size() {
		return map.size();
	}
	
	@Override
	public boolean add(E e) {
		return map.put(e, persent) == null;
	}
	
	/**
	 * 私有非静态内部类
	 * @author lzy
	 *
	 * @param <E>
	 */
	private class MyIterator implements Iterator<E>{

		private final Iterator<E> i;
		
		public MyIterator(){
			i = map.keySet().iterator();
		}
		
		public boolean hasNext() {
			return i.hasNext();
		}

		public E next() {
			return i.next();
		}

		public void remove() {
			i.remove();
		}
		
	}
	
	private static class Person extends Object implements Cloneable{
		private String name;
		private int age;
		public Person(String name, int age) {
			super();
			this.name = name;
			this.age = age;
		}
		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
		public int getAge() {
			return age;
		}
		
		@Override
		public String toString() {
			return "[name="+name+",age="+age+"]";
		}
		
		
		
		@Override
		protected Person clone() throws CloneNotSupportedException {
			Person per = (Person) super.clone();
			return per;
		}
		
		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + age;
			result = prime * result + ((name == null) ? 0 : name.hashCode());
			return result;
		}
		
		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (!(obj instanceof Person))
				return false;
			Person other = (Person) obj;
			if (age != other.age)
				return false;
			if (name == null) {
				if (other.name != null)
					return false;
			} else if (!name.equals(other.name))
				return false;
			return true;
		}
		
		public void setAge(int age) {
			this.age = age;
		}
		
	}
	
	public static void main(String[] args) {
		List<Person> l = new ArrayList<Person>();
		l.add(new Person("a",1));
		l.add(new Person("b",2));
		MySet<Person> set = new MySet<Person>(l);
		set.add(new Person("c",4));
		System.out.println(set);
		set.remove(new Person("a",1));
		System.out.println(set);
	}
}
